//
// Created on 2025/1/23.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "camera_factory_helper.h"
#include "napi_utils.h"
#include "Log.h"
#include "PluginManager.h"

bool DEBUG_ENABLE = false;


static napi_value nativeEnableDebug(napi_env env, napi_callback_info info) {
    napi_value args[1] = {0};
    size_t argc = 1;
    // 获取传递进来的值
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return napiUtils::createIntNapi(env, 0);
    }
    int debugStatus;
    if (!napiUtils::loadNapiInt(env, args[0], &debugStatus)) {
        return napiUtils::createIntNapi(env, 0);
    }
    DEBUG_ENABLE = debugStatus == 1;
    LOG_D("当前的debug状态:%{public}s", DEBUG_ENABLE ? "打开" : "关闭");
    return napiUtils::createIntNapi(env, 1);
}

static napi_value nativeOpen(napi_env env, napi_callback_info info) {
    napi_value args[1] = {0};
    size_t argc = 1;
    // 获取传递进来的值
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return nullptr;
    }
    char *videoPath = napiUtils::loadNapiString(env, args[0]);
    if (!videoPath) {
        return nullptr;
    }
    auto result = CameraFactoryHelper::openCamera(videoPath);
    SAFE_FREE(videoPath);
    if (!result) {
        return nullptr;
    }
    return napiUtils::createLongNapi(env, reinterpret_cast<int64_t>(result));
}
static napi_value nativeClose(napi_env env, napi_callback_info info) {
    napi_value args[1] = {0};
    size_t argc = 1;
    // 获取传递进来的值
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return napiUtils::createIntNapi(env, 0);
    }
    int64_t cameraId;
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId)) {
        return napiUtils::createIntNapi(env, 0);
    }
    if (!CameraFactoryHelper::close(cameraId)) {
        return napiUtils::createIntNapi(env, 0);
    }
    return napiUtils::createIntNapi(env, 1);
}

static napi_value nativeGetSupportParameter(napi_env env, napi_callback_info info) {
    napi_value args[2] = {0};
    size_t argc = 2;
    // 获取传递进来的值
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return nullptr;
    }
    int64_t cameraId;
    int type;
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId) || !napiUtils::loadNapiInt(env, args[1], &type)) {
        return nullptr;
    }
    ICameraFactory *camera = reinterpret_cast<ICameraFactory *>(cameraId);
    if (camera) {
        auto result = camera->getSupportParameters(type);
        if (result) {
            auto resultStr = napiUtils::createStringNapi(env, result);
            SAFE_FREE(result);
            return resultStr;
        }
    }
    return nullptr;
}
static napi_value nativeStartPreview(napi_env env, napi_callback_info info) {
    napi_value args[1] = {0};
    size_t argc = 1;
    // 获取传递进来的值
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return napiUtils::createIntNapi(env, 0);
    }
    int64_t cameraId;
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId)) {
        return napiUtils::createIntNapi(env, 0);
    }
    ICameraFactory *camera = reinterpret_cast<ICameraFactory *>(cameraId);
    if (camera) {
        auto result = camera->startPreview();
        if (result) {
            return napiUtils::createIntNapi(env, result ? 1 : 0);
        }
    }
    return napiUtils::createIntNapi(env, 0);
}

static napi_value nativeStopPreview(napi_env env, napi_callback_info info) {
    napi_value args[1] = {0};
    size_t argc = 1;
    // 获取传递进来的值
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return napiUtils::createIntNapi(env, 0);
    }
    int64_t cameraId;
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId)) {
        return napiUtils::createIntNapi(env, 0);
    }
    ICameraFactory *camera = reinterpret_cast<ICameraFactory *>(cameraId);
    if (camera) {
        auto result = camera->stopPreview();
        if (result) {
            return napiUtils::createIntNapi(env, result ? 1 : 0);
        }
    }
    return napiUtils::createIntNapi(env, 0);
}

static napi_value nativeSetPreviewSize(napi_env env, napi_callback_info info) {
    napi_value args[4] = {0};
    size_t argc = 4;
    // 获取传递进来的值

    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return nullptr;
    }
    int64_t cameraId;
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId)) {
        return napiUtils::createIntNapi(env, 0);
    }
    ICameraFactory *camera = reinterpret_cast<ICameraFactory *>(cameraId);
    int32_t width;
    int32_t height;
    int32_t format;
    if (!napiUtils::loadNapiInt(env, args[1], &width) || !napiUtils::loadNapiInt(env, args[2], &height) ||
        !napiUtils::loadNapiInt(env, args[3], &format)) {
        return napiUtils::createIntNapi(env, 0);
    }
    if (camera) {
        int ret = camera->setPreviewSize(width, height, format);
        return napiUtils::createIntNapi(env, ret ? 1 : 0);
    }
    return napiUtils::createIntNapi(env, 0);
}

static napi_value nativeSetDisplaySurface(napi_env env, napi_callback_info info) {
    napi_value args[2] = {0};
    size_t argc = 2;
    // 获取传递进来的值

    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return napiUtils::createIntNapi(env, 0);
    }
    int64_t cameraId;
    char *surfaceId = napiUtils::loadNapiString(env, args[1]);
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId) || !surfaceId) {
        return napiUtils::createIntNapi(env, 0);
    }
    ICameraFactory *camera = reinterpret_cast<ICameraFactory *>(cameraId);
    if (camera) {
        int ret = camera->setDisplaySurface(surfaceId);
        return napiUtils::createIntNapi(env, ret ? 1 : 0);
    }
    SAFE_FREE(surfaceId);
    return napiUtils::createIntNapi(env, 0);
}

static napi_value nativeSetPreviewListener(napi_env env, napi_callback_info info) {
    napi_value args[3] = {0};
    size_t argc = 3;
    // 获取传递进来的值

    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return napiUtils::createIntNapi(env, 0);
    }
    int64_t cameraId;
    int32_t mode;
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId) || !napiUtils::loadNapiInt(env, args[2], &mode)) {
        return napiUtils::createIntNapi(env, 0);
    }
    ICameraFactory *camera = reinterpret_cast<ICameraFactory *>(cameraId);
    if (camera) {
        camera->setPreviewDataListener(env, args[1], mode);
        return napiUtils::createIntNapi(env, 1);
    }
    return napiUtils::createIntNapi(env, 0);
}

static napi_value nativeGetParameterValue(napi_env env, napi_callback_info info) {
    napi_value args[2] = {0};
    size_t argc = 2;
    // 获取传递进来的值

    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return nullptr;
    }
    int64_t cameraId;
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId)) {
        return nullptr;
    }
    int type;
    if (!napiUtils::loadNapiInt(env, args[1], &type)) {
        return nullptr;
    }
    ICameraFactory *camera = reinterpret_cast<ICameraFactory *>(cameraId);
    if (camera) {
        char *value = camera->getParameter(type);
        napi_value resultStr = napiUtils::createStringNapi(env, value);
        SAFE_FREE(value);
        return resultStr;
    }
    return nullptr;
}

static napi_value nativeSetParameterValue(napi_env env, napi_callback_info info) {
    napi_value args[3] = {0};
    size_t argc = 3;
    // 获取传递进来的值
    if (napi_get_cb_info(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
        return napiUtils::createIntNapi(env, 0);
    }
    int64_t cameraId;
    if (!napiUtils::loadNapiLong(env, args[0], &cameraId)) {
        return napiUtils::createIntNapi(env, 0);
    }
    int type;
    if (!napiUtils::loadNapiInt(env, args[1], &type)) {
        return napiUtils::createIntNapi(env, 0);
    }
    char *value = napiUtils::loadNapiString(env, args[2]);
    if (!value) {
        return napiUtils::createIntNapi(env, 0);
    }
    ICameraFactory *camera = reinterpret_cast<ICameraFactory *>(cameraId);
    if (camera) {
        bool ret = camera->setParameter(type, value);
        SAFE_FREE(value);
        return napiUtils::createIntNapi(env, ret ? 1 : 0);
    }
    SAFE_FREE(value);
    return napiUtils::createIntNapi(env, 0);
}
EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {
        // 方法描述列表
        {"nativeEnableDebug", nullptr, nativeEnableDebug, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeOpen", nullptr, nativeOpen, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeClose", nullptr, nativeClose, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeStartPreview", nullptr, nativeStartPreview, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeStopPreview", nullptr, nativeStopPreview, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeSetPreviewSize", nullptr, nativeSetPreviewSize, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeSetDisplaySurface", nullptr, nativeSetDisplaySurface, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeSetPreviewListener", nullptr, nativeSetPreviewListener, nullptr, nullptr, nullptr, napi_default,
         nullptr},
        {"nativeGetParameterValue", nullptr, nativeGetParameterValue, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeSetParameterValue", nullptr, nativeSetParameterValue, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"nativeGetSupportParameter", nullptr, nativeGetSupportParameter, nullptr, nullptr, nullptr, napi_default,
         nullptr},
    };
    LOG_D("HomeNavigation native Init");
    napi_status status = napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    LOG_D("HomeNavigation native status:%{public}d", status == napi_ok);
    if (status != napi_ok) {
        return nullptr;
    }
    //    开始读取传入的surface数据
    PluginManager::GetInstance()->Export(env, exports);
    return exports;
}
EXTERN_C_END


// 模块配置
static napi_module usb_videoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "usb_video",
    .nm_priv = ((void *)0),
    .reserved = {0},
};
extern "C" __attribute__((constructor)) void RegisterUsb_videoModule(void) {
    napi_module_register(&usb_videoModule); // 注册模块
}